Set of wires (quantum register) on which a sequence of quantum gates is applied.
A quantum circuit represents our computation.
Each gate is a transformation.
Some properties:
%matplotlib inline
from qiskit.circuit.random import random_circuit
random_circuit(4, 4).draw(output='mpl')
This platform lets you access some quantum processors for free, through the cloud. The user interacts with IBM machines using quantum circuits through the Python library Qiskit.
Can be found on Qiskit Learn.
Main resource: Qiskit textbook
Some interesting videos on the Youtube channel.

Some practical things you can do to learn about quantum computing
Quantum Intuition (Youtube) (website)
%matplotlib inline
from qiskit import *
from math import pi
qiskit.__qiskit_version__
qreg = QuantumRegister(2, "qr")
creg = ClassicalRegister(2, "cr")
circuit = QuantumCircuit(qreg, creg)
circuit.draw()
circuit.h(qreg[0])
circuit.draw(output='mpl')
circuit.cx(qreg[0], qreg[1])
circuit.draw(output='mpl')
circuit.measure(qreg, creg)
circuit.draw(output='mpl')
simulator = Aer.get_backend('qasm_simulator')
result = execute(circuit, backend=simulator, shots=1024).result()
from qiskit.tools.visualization import plot_histogram
plot_histogram(result.get_counts())

IBMQ.save_account("XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
overwrite=True)
# 401 Client Error: Unauthorized for url: https://auth.quantum-computing.ibm.com/api/users/loginWithToken
IBMQ.load_account()
provider = IBMQ.get_provider('ibm-q')
qcomp = provider.get_backend('ibmq_5_yorktown')
job = execute(circuit, backend=qcomp, shots=1024)
from qiskit.tools.monitor import job_monitor
job_monitor(job)
result_2 = job.result()
plot_histogram([result.get_counts(), result_2.get_counts()])
circuit = QuantumCircuit(1)
circuit.x(0)
unitary = execute(circuit, backend=Aer.get_backend('unitary_simulator')).result().get_unitary()
unitary
import kaleidoscope.qiskit
from kaleidoscope import qsphere, bloch_sphere
from qiskit.quantum_info import Statevector
circuit = QuantumCircuit(1)
circuit.x(0)
# statevector = execute(circuit, backend=Aer.get_backend('statevector_simulator')).result().get_statevector()
statevector = Statevector.from_instruction(circuit)
qsphere(statevector)
circuit = QuantumCircuit(1)
statevector = execute(circuit, backend=Aer.get_backend('statevector_simulator')).result().get_statevector()
qsphere(statevector)
circuit = QuantumCircuit(1)
circuit.x(0)
qsphere(circuit.statevector())
circuit = QuantumCircuit(1)
circuit.rx(pi/4, 0)
bloch_sphere(circuit.statevector())
qsphere(circuit.statevector())
Partendo da $\theta$:
circuit = QuantumCircuit(1)
circuit.y(0)
qsphere(Statevector.from_instruction(circuit))
circuit = QuantumCircuit(1)
circuit.x(0)
circuit.z(0)
qsphere(circuit.statevector())
circuit = QuantumCircuit(1)
circuit.h(0)
qsphere(circuit.statevector())
Source-to-source compiler, its input is the circuit, and the name of a specific architecture. Its output is an equivalent circuit that can run on that specific architecture, optimized.
circuit = QuantumCircuit(2)
circuit.h(0)
circuit.crx(0.12, 0,1)
circuit.draw(output="mpl")
provider = IBMQ.get_provider('ibm-q')
backend = provider.get_backend('ibmq_5_yorktown')
new_circuit = transpile(circuit, backend)
new_circuit.draw()
A single qubit can be initialized with a $u3$ gate:
$$ u3(\theta, \phi, \lambda) = \begin{bmatrix} \cos(\theta/2) & - e^{i \lambda} \sin(\theta/2) \\ e^{i \phi} \sin(\theta/2) & e^{i \phi + i \lambda} cos(\theta/2) \end{bmatrix} $$$$ u3(\frac{\pi}{2}, \frac{\pi}{2}, \frac{\pi}{2}) = = \begin{bmatrix} \cos(\pi/4) & - e^{i \pi/2} \sin(\pi/4) \\ e^{i \pi/2} \sin(\pi/4) & e^{i \pi} \cos(\pi/4) \end{bmatrix} = \begin{bmatrix} .707 & - i .707 \\ i .707 & - .707 \end{bmatrix}$$qc = QuantumCircuit(1)
qc.u3(pi/2, pi/2, pi/2, 0)
qc.draw()
job = execute(qc, Aer.get_backend('unitary_simulator'))
array = job.result().get_unitary(qc)
# rounding result
for i in range(0,2):
for j in range(0,2):
a = round(array[i][j].real, 3)
b = round(array[i][j].imag, 3)
array[i][j] = complex(a, b)
array
import numpy as np
import math
desired_vector = [
1 / math.sqrt(16) * complex(0, 1),
1 / math.sqrt(8) * complex(1, 0),
1 / math.sqrt(16) * complex(1, 1),
0,
0,
1 / math.sqrt(8) * complex(1, 2),
1 / math.sqrt(16) * complex(1, 0),
0]
print("Amplitude: ", np.linalg.norm(desired_vector))
circuit = QuantumCircuit(3)
circuit.initialize(desired_vector, [0, 1, 2] )
circuit.draw()
provider = IBMQ.get_provider('ibm-q')
backend = provider.get_backend('ibmq_5_yorktown')
new_circuit = transpile(circuit, backend)
new_circuit.draw()
new_circuit.size()
Try with a random generated state...
from qiskit.quantum_info.states.random import random_statevector
def check_circuit_size(dim, qubits, machine_name='ibmq_5_yorktown'):
wanted_state = random_statevector(dim).data
circuit = QuantumCircuit(len(qubits))
circuit.initialize(wanted_state, qubits )
circuit.draw()
provider = IBMQ.get_provider('ibm-q')
backend = provider.get_backend(machine_name)
new_circuit = transpile(circuit, backend)
size = new_circuit.size()
print("{}: Filling {} qubits => {} elements => {} gates".format(machine_name, len(qubits), dim, size))
check_circuit_size( 8, [0, 1, 2])
check_circuit_size(16, [0, 1, 2, 3])
check_circuit_size(32, [0, 1, 2, 3, 4])
check_circuit_size( 8, [0, 1, 2], machine_name='ibmq_16_melbourne')
check_circuit_size(16, [0, 1, 2, 3], machine_name='ibmq_16_melbourne')
check_circuit_size(32, [0, 1, 2, 3, 4], machine_name='ibmq_16_melbourne')
check_circuit_size(64, [0, 1, 2, 3, 4, 5], machine_name='ibmq_16_melbourne')
check_circuit_size(128, [0, 1, 2, 3, 4, 5, 6], machine_name='ibmq_16_melbourne')
check_circuit_size(256, [0, 1, 2, 3, 4, 5, 6, 7], machine_name='ibmq_16_melbourne')